#include "types.h"
#include "grammar.h"
#include "malloc.h"


/*
 * expr: add_expr;
 *
 * add_op: '+' | '-'
 * 
 * add_expr: mul_expr (add_op mul_expr)*;
 *
 * mul_op: '*' | '/' | '%'
 * 
 * mul_expr: factor_expr (mul_op factor_expr)*;
 *
 * factor_expr: number | EOF;
 */

static uint64_t bus_parse_value;

static uint64_t bus_batch_factor()
{
	int token;
	u64 value;
	token = lexer_get_token(&value, 0, 0);
	switch(token) {
	case NUM:
		goto out;
	case NOT:
		value = ~(bus_batch_factor());
		goto out;
	case ADD:
		value = +(bus_batch_factor());
		goto out;
	case SUB:
		value = -(bus_batch_factor());
		goto out;
	case LB:
		value = bus_batch_expr();
		if(lexer_get_token(0, 0, 0) != RB) {
			value = BADTOK;
		}
		goto out;
	}
out:
	return value;
}

static uint64_t bus_batch_mul_op()
{
	int token;
	u8 **string;
	int len;
	u64 value;
	token = lexer_get_token(&value, &string, &len);
	switch(token) {
	case MUL:
		value = MUL;
		goto out;
	case DIV:
		value = DIV;
		goto out;
	default:
		value = BADTOK;
		goto out;
	}
out:
	return value;
}

static uint64_t bus_batch_mul_expr()
{
	int token;
	u64 value;
	value = bus_batch_factor();
	while((token = bus_batch_mul_op()) != BADTOK) {
		if(token == MUL)
			value *= bus_batch_factor();
		if(token == DIV)
			value /= bus_batch_factor();
	}
out:
	return value;
}

static uint64_t bus_batch_add_op()
{
	int token;
	u8 **string;
	int len;
	u64 value;
	token = lexer_get_token(&value, &string, &len);
	switch(token) {
	case ADD:
		value = ADD;
		goto out;
	case SUB:
		value = SUB;
		goto out;
	default:
		value = BADTOK;
		goto out;

	}
out:
	return value;
}

static uint64_t bus_batch_add_expr()
{
	int token;
	u64 value;
	value = bus_batch_mul_expr();
	while((token = bus_batch_mul_op()) != BADTOK) {
		if(token == ADD)
			value += bus_batch_mul_expr();
		if(token == SUB)
			value -= bus_batch_mul_expr();
	}
out:
	return value;
}

int function_definition()
{

}

int external_declaration()
{

}

int translation_unit()
{

}

int jump_statement()
{

}

int iteration_statement()
{

}

int selection_statement()
{

}

int expression_statement()
{

}

int statement_list()
{

}

int declaration_list()
{

}

int compound_statement()
{

}

int labeled_statement()
{

}

int statement()
{

}

int initializer_list()
{

}

int initializer()
{

}

int direct_abstract_declarator()
{

}

int abstract_declarator()
{

}

int type_name()
{

}

int identifier_list()
{

}

int parameter_declaration()
{

}

int parameter_list()
{

}

int parameter_type_list()
{

}

int type_qualifier_list()
{

}

int pointer()
{

}
